﻿//===============================================================================
// Magic OQL
//===============================================================================
// Copyright ?Magic Thought Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// Richie (http://www.cnblogs.com/RicCC)
// March 10, 2008
//===============================================================================

using Antlr.Runtime;
using Antlr.Runtime.Tree;

namespace SQLAnalyticLibrary.Expressions.Predicate
{
    /// <summary>
    /// expression BETWEEN exp1 AND exp2
    /// child 0: expression
    /// child 1: exp1
    /// child 2: AND (TextNode)
    /// child 3: exp2
    /// </summary>
    public class Between : Expression
    {
        private int _childIndex = 0;

        public Between(IToken t)
            : base(t)
        {
        }
        public Between(Between t)
            : base(t.Token)
        {
            this._childIndex = t._childIndex;
            this._children = t._children;
        }
        /// <summary>
        /// NOT? BETWEEN expressions AND expressions
        ///    -> ^(BETWEEN ^(TextNode NOT? BETWEEN) expressions expressions ^(TextNode AND) expressions)
        /// </summary>
        /// <param name="t"></param>
        public override void AddChild(Expression t)
        {
            if (t == null)
            {
                this.InternalAddChild(t);
                return;
            }
            if (this._childIndex == 0 && SQLAnalyticLibrary.Expressions.Text.IsText(t))
            {
                this.Token.Text = t.ToString();
                this._childIndex++;
                return;
            }
            //if (this._childIndex == 0 && SQLAnalyticLibrary.Expressions.Text.IsText(t._children[0]))
            //{
            //    this.Token.Text = t._children[0].ToString();
            //    t._children.Remove(t._children[0]);
            //    this._childIndex++;
            //}
            this.InternalAddChild(t);
        }

        public override Expression DupNode()
        {
            return new Between(this);
        }

        public override void VisitSql(ISqlVisitor visitor)
        {
            // expression BETWEEN exp1 AND exp2
            // child 0: expression
            // child 1: exp1
            // child 2: AND (TextNode)
            // child 3: exp2
            if (this._children == null || this._children.Count != 4) return;
            this._children[0].VisitSql(visitor); //expression
            visitor.Space();
            visitor.Sql(this.ToString()); //BETWEEN keyword
            visitor.Space();
            this._children[1].VisitSql(visitor); //exp1
            visitor.Space();
            this._children[2].VisitSql(visitor); //AND keyword
            visitor.Space();
            this._children[3].VisitSql(visitor); //exp2
        }

        internal static int TreeType
        {
            get
            {
                return OQLParser.BETWEEN;
            }
        }
    }
}
